package com.quanyan.comment.service.impl;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.quanyan.api.APIResponse;
import com.quanyan.comment.mapper.CommentTagUserMapper;
import com.quanyan.comment.mapper.TbCommentTagMapper;
import com.quanyan.comment.mapper.TbCommentTagSumMapper;
import com.quanyan.comment.mapper.TbSysLabelGroupMapper;
import com.quanyan.comment.model.po.*;
import com.quanyan.comment.model.po.TbCommentTag;
import com.quanyan.comment.model.po.TbCommentTagExample;
import com.quanyan.comment.model.po.TbCommentTagSum;
import com.quanyan.comment.model.po.TbCommentTagSumExample;
import com.quanyan.comment.reqeust.ReqCommentQuery;
import com.quanyan.comment.reqeust.ReqCommentTag;
import com.quanyan.comment.response.LableBaseInfo;
import com.quanyan.comment.response.RespCommentTag;
import com.quanyan.comment.service.CommentTagService;
import com.quanyan.common.constants.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created by Administrator on 2016/12/9.
 * 评论标签
 */
@Service
public class CommentTagServiceImpl implements CommentTagService {

    private static final Logger logger = LoggerFactory.getLogger(CommentTagServiceImpl.class);

    @Autowired
    private TbCommentTagMapper tbCommentTagMapper;


    @Autowired
    private TbCommentTagSumMapper tbCommentTagSumMapper;


    @Autowired
    private CommentTagUserMapper commentTagUserMapper;

    @Autowired
    private TbSysLabelGroupMapper tbSysLabelGroupMapper;


    public List<TbCommentTag> findCommentTag(ReqCommentQuery reqCommentQuery) {
        TbCommentTagExample tbCommentTagExample = new TbCommentTagExample();
        TbCommentTagExample.Criteria criteria = tbCommentTagExample.createCriteria();

        if (reqCommentQuery.getCategory_id() == null || reqCommentQuery.getCategory_id().intValue() == 0) {
            criteria.andSystemCodeEqualTo(reqCommentQuery.getSystemCode());
            criteria.andBusinessCodeEqualTo(reqCommentQuery.getBusinessCode());
        } else {
            criteria.andCategoryIdEqualTo(reqCommentQuery.getCategory_id().byteValue());
            criteria.andMoudleEqualTo(Constants.SystemMoudle.daren);
        }
        criteria.andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        return tbCommentTagMapper.selectByExample(tbCommentTagExample);
    }

    public void insertCommentTag(ReqCommentTag reqCommentTag) {
        TbCommentTag tbCommentTag = new TbCommentTag();
        tbCommentTag.setSystemCode(reqCommentTag.getSystemCode());
        tbCommentTag.setBusinessCode(reqCommentTag.getBusinessCode());
        tbCommentTag.setBusinessId(reqCommentTag.getBusinessId());
        tbCommentTag.setCommonParam(reqCommentTag.getCommonParam().toString());
        tbCommentTag.setTagName(reqCommentTag.getTagName());
        tbCommentTag.setType(reqCommentTag.getType());
        tbCommentTagMapper.insertSelective(tbCommentTag);
    }


    public void updateCommentTag(ReqCommentTag reqCommentTag) {
        TbCommentTag tbCommentTag = new TbCommentTag();
        tbCommentTag.setId(reqCommentTag.getTagId());
        if (reqCommentTag.getTagName() != null && !"".equals(reqCommentTag.getTagName()))
            tbCommentTag.setTagName(reqCommentTag.getTagName());
        if (reqCommentTag.getType() != 0)
            tbCommentTag.setType(reqCommentTag.getType());
        tbCommentTag.setIsDelete(reqCommentTag.getIsDelete());
        tbCommentTagMapper.updateByPrimaryKeySelective(tbCommentTag);
    }

    public APIResponse commentTagUpdate(ReqCommentTag reqCommentTag) {
        logger.info("[commentTag update ] start ,{}", reqCommentTag.toString());
        try {
            this.updateCommentTag(reqCommentTag);
            logger.info("[commentTag update end ]");
            return APIResponse.returnSuccess();
        } catch (Exception e) {
            logger.error("[commentTag query ] error", e);
            return APIResponse.returnFail("系统异常");
        }

    }

    public APIResponse commentTagInsert(ReqCommentTag reqCommentTag) {
        logger.info("[commentTag insert ] start ,{}", reqCommentTag.toString());
        try {
            this.insertCommentTag(reqCommentTag);
            logger.info("[commentTag insert end ]");
            return APIResponse.returnSuccess();
        } catch (Exception e) {
            logger.error("[commentTag query ] error", e);
            return APIResponse.returnFail("系统异常");
        }
    }


    public APIResponse<List<RespCommentTag>> commentTagQuery(ReqCommentQuery reqCommentQuery) {
        logger.info("[commentTag query ] start ,{}", reqCommentQuery.toString());
        List<RespCommentTag> lstRespCommentTag = null;
        try {
            Integer category_id = 0;
            //2：评价标签
            if (Constants.DAREN_SYSTEM_CODE.equals(reqCommentQuery.getSystemCode())) {
                category_id = 2;
            }
            reqCommentQuery.setCategory_id(category_id);
            List<TbCommentTag> tbCommentTagList = this.findCommentTag(reqCommentQuery);
            if (tbCommentTagList != null && tbCommentTagList.size() > 0) {
                lstRespCommentTag = new ArrayList<>();
                for (TbCommentTag tbCommentTag : tbCommentTagList) {
                    RespCommentTag respCommentTag = new RespCommentTag();
                    respCommentTag.setId(tbCommentTag.getId());
                    respCommentTag.setTagName(tbCommentTag.getTagName());
                    respCommentTag.setType(tbCommentTag.getType());
                    respCommentTag.setPepTotal(tbCommentTag.getPepTotal());
                    lstRespCommentTag.add(respCommentTag);
                }
                logger.info("[commentTag query ] result ,{}", lstRespCommentTag.toString());
            }
            logger.info("[commentTag query ] end");
        } catch (Exception e) {
            logger.error("[commentTag query ] error", e);
            return APIResponse.returnFail("系统异常");
        }

        return APIResponse.returnSuccess(lstRespCommentTag);
    }


    public Map<Integer, TbCommentTag> batchCommentTagById(List<Integer> listId) {
        TbCommentTagExample tbCommentTagExample = new TbCommentTagExample();
        TbCommentTagExample.Criteria criteria = tbCommentTagExample.createCriteria();
        criteria.andIdIn(listId);
        List<TbCommentTag> tbCommentTagList = tbCommentTagMapper.selectByExample(tbCommentTagExample);
        if (tbCommentTagList != null && tbCommentTagList.size() > 0)
            return Maps.uniqueIndex(tbCommentTagList, this.getTbCommentTagMap());
        return new HashMap<>();
    }


    public Function<TbCommentTag, Integer> getTbCommentTagMap() {
        return new Function<TbCommentTag, Integer>() {
            @Override
            public Integer apply(TbCommentTag input) {
                return input.getId();
            }
        };
    }


    /***
     * @param tbCommentTagSumList
     * @param listTagId
     */
    public void commentTagTotal(List<TbCommentTagSum> tbCommentTagSumList, List<Integer> listTagId) {
        TbCommentTagSumExample tbCommentTagSumExample = new TbCommentTagSumExample();
        TbCommentTagSumExample.Criteria criteria = tbCommentTagSumExample.createCriteria();
        criteria.andSystemCodeEqualTo(tbCommentTagSumList.get(0).getSystemCode());
        criteria.andBusinessCodeEqualTo(tbCommentTagSumList.get(0).getBusinessCode());
        criteria.andBusinessIdEqualTo(tbCommentTagSumList.get(0).getBusinessId());
        criteria.andTagIdIn(listTagId);
        List<TbCommentTagSum> commentTagSumList = tbCommentTagSumMapper.selectByExample(tbCommentTagSumExample); //13

        if (commentTagSumList != null && commentTagSumList.size() > 0) {
            List<Integer> listId = new ArrayList<>();//db update
            listId.addAll(this.getCommentTagSumUpdateId(commentTagSumList).asList());

            Set<Integer> result = new HashSet<>();
            Set<Integer> setQuery = new HashSet<>();
            Set<Integer> setDb = new HashSet<>();
            setQuery.addAll(this.getTagIdTbCommentTagSum(tbCommentTagSumList).asList());
            setDb.addAll(this.getTagIdTbCommentTagSum(commentTagSumList).asList());
            result.addAll(setQuery);
            result.addAll(setDb);
            setQuery.retainAll(setDb);//交集
            result.removeAll(setQuery);

            if (listId.size() > 0)
                commentTagUserMapper.batchUpdateTagSum(listId);
            if (result.size() > 0) {
                List<TbCommentTagSum> tbCommentTagSums = new ArrayList<>();
                for (TbCommentTagSum tbCommentTagSum : tbCommentTagSumList) {
                    for (Integer tagId : result) {
                        if (tagId.intValue() == tbCommentTagSum.getTagId().intValue()) {
                            tbCommentTagSums.add(tbCommentTagSum);
                        }
                    }
                }
                commentTagUserMapper.batchSaveTagSum(tbCommentTagSums);
            }

        } else {
            commentTagUserMapper.batchSaveTagSum(tbCommentTagSumList);
        }
    }


    public List<RespCommentTag> commentTagSum(ReqCommentQuery reqCommentQuery) {
        TbCommentTagSumExample tbCommentTagSumExample = new TbCommentTagSumExample();
        TbCommentTagSumExample.Criteria criteria = tbCommentTagSumExample.createCriteria();
        criteria.andSystemCodeEqualTo(reqCommentQuery.getSystemCode());
        criteria.andBusinessCodeEqualTo(reqCommentQuery.getBusinessCode());
        criteria.andBusinessIdEqualTo(reqCommentQuery.getBusinessId());
        List<TbCommentTagSum> commentTagSumList = tbCommentTagSumMapper.selectByExample(tbCommentTagSumExample);

        List<RespCommentTag> respCommentTagList = new ArrayList<>();
        if (commentTagSumList != null && commentTagSumList.size() > 0) {
            for (TbCommentTagSum tbCommentTagSum : commentTagSumList) {
                RespCommentTag respCommentTag = new RespCommentTag();
                respCommentTag.setTagName(tbCommentTagSum.getTagName());
                respCommentTag.setId(tbCommentTagSum.getTagId());
                respCommentTag.setPepTotal(tbCommentTagSum.getPepTotal());
                respCommentTagList.add(respCommentTag);
            }
        }
        return respCommentTagList;
    }


    public List<TbSysLabelGroup> queryGroupLabel(byte category_id) {
        TbSysLabelGroupExample tbSysLabelGroupExample = new TbSysLabelGroupExample();
        TbSysLabelGroupExample.Criteria criteria = tbSysLabelGroupExample.createCriteria();
        criteria.andIsDeleteEqualTo(false);
        criteria.andCategoryIdEqualTo(category_id);
        return tbSysLabelGroupMapper.selectByExample(tbSysLabelGroupExample);
    }

    public List<RespCommentTag> queryDarenTag(byte category_id) {
        List<RespCommentTag> lstRespCommentTag = null;
        TbCommentTagExample tbCommentTagExample = new TbCommentTagExample();
        TbCommentTagExample.Criteria criteria = tbCommentTagExample.createCriteria();
        criteria.andMoudleEqualTo(Constants.SystemMoudle.daren);
        criteria.andCategoryIdEqualTo(category_id);
        criteria.andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        List<TbCommentTag> tbCommentTagList = tbCommentTagMapper.selectByExample(tbCommentTagExample);
        if (tbCommentTagList != null && tbCommentTagList.size() > 0) {
            lstRespCommentTag = new ArrayList<>();
            for (TbCommentTag tbCommentTag : tbCommentTagList) {
                RespCommentTag respCommentTag = new RespCommentTag();
                respCommentTag.setId(tbCommentTag.getId());
                respCommentTag.setTagName(tbCommentTag.getTagName());
                respCommentTag.setType(tbCommentTag.getType());
                respCommentTag.setPepTotal(tbCommentTag.getPepTotal());
                respCommentTag.setGroupId(tbCommentTag.getGroupId());
                lstRespCommentTag.add(respCommentTag);
            }
            logger.info("[commentTag query ] result ,{}", lstRespCommentTag.toString());
        }
        return lstRespCommentTag;
    }


    /**
     * id 批量查询
     *
     * @param ids
     * @return
     */
    public List<LableBaseInfo> batchTagByIds(List<Integer> ids) {
        List<LableBaseInfo> result = null;
        if (ids != null && ids.size() > 0) {
            TbCommentTagExample tbCommentTagExample = new TbCommentTagExample();
            TbCommentTagExample.Criteria criteria = tbCommentTagExample.createCriteria();
            criteria.andIdIn(ids);
            List<TbCommentTag> tbCommentTagList = tbCommentTagMapper.selectByExample(tbCommentTagExample);
            if (tbCommentTagList != null && tbCommentTagList.size() > 0) {
                result = new ArrayList<>();
                for (TbCommentTag tbCommentTag : tbCommentTagList) {
                    LableBaseInfo lableBaseInfo = new LableBaseInfo();
                    lableBaseInfo.setId(tbCommentTag.getId());
                    lableBaseInfo.setType(tbCommentTag.getCategoryId());
                    lableBaseInfo.setText(tbCommentTag.getTagName());
                    result.add(lableBaseInfo);
                }
            }
        }
        return result;
    }


    public List<LableBaseInfo> randTags(Integer pageSize) {
        return commentTagUserMapper.randTag(pageSize);
    }


    //list 按属性生成一个新的 list
    public ImmutableMultiset<Integer> getCommentTagSumUpdateId(List<TbCommentTagSum> list) {
        return ImmutableMultiset.copyOf(Lists.transform(list, new Function<TbCommentTagSum, Integer>() {
                    @Override
                    public Integer apply(TbCommentTagSum input) {
                        return input.getId();
                    }
                }
        ));
    }

    //list 按属性生成一个新的 list
    public ImmutableMultiset<Integer> getTagIdTbCommentTagSum(List<TbCommentTagSum> list) {
        return ImmutableMultiset.copyOf(Lists.transform(list, new Function<TbCommentTagSum, Integer>() {
                    @Override
                    public Integer apply(TbCommentTagSum input) {
                        return input.getTagId();
                    }
                }
        ));
    }

}
